package work.xiaohong.websocket.controller;

import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.yeauty.pojo.Session;
import work.xiaohong.common.constant.MessageStatus;
import work.xiaohong.common.constant.MessageType;
import work.xiaohong.common.constant.StatusCode;
import work.xiaohong.common.eneity.PageResult;
import work.xiaohong.common.eneity.Result;
import work.xiaohong.websocket.client.MyWebSocketClient;
import work.xiaohong.websocket.entity.SingleMessage;
import work.xiaohong.websocket.service.SendMsgVoService;
import work.xiaohong.websocket.service.SingleMessageService;
import work.xiaohong.websocket.valid.ReceiverGroup;
import work.xiaohong.websocket.valid.SenderAndReceiverGroup;
import work.xiaohong.websocket.valid.SenderGroup;
import work.xiaohong.websocket.vo.ForwardMsgVo;
import work.xiaohong.websocket.vo.MsgListVo;
import work.xiaohong.websocket.vo.SendMsgVo;
import work.xiaohong.websocket.vo.UpdateMsgStatusVo;

import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author xiaohong
 * @version 1.0
 * @date 2021/9/25 0025 13:35
 * @description 单聊接口
 */
@Tag(name = "单聊接口文档",description = "这是一个单聊接口文档")
@RestController
@SuppressWarnings("all")
@RequestMapping("/single")
@CrossOrigin
public class SingleChatController {

    @Autowired
    private MyWebSocketClient myWebSocketClient;

    @Autowired
    private SingleMessageService singleMessageService;

    @Autowired
    private SendMsgVoService sendMsgVoService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 发送消息
     * @param sendMsgVo
     * @return
     * @throws ParseException
     */
    @Operation(summary = "发送消息",description = "所需权限：",security ={@SecurityRequirement(name ="Authorization")})
    @PostMapping("/send")
    public Result sendMsg(@Validated  @RequestBody SendMsgVo message) throws ParseException {

        // 设置消息状态为发送中
        message.setStatus(MessageStatus.SENDING.getStatus());
        Session receiver = myWebSocketClient.chatClients.get(message.getReceiver());

        if (message.getType() == MessageType.HEART.getType()){
            // 心跳消息
            message.setType(MessageType.HEARTRESPONSE.getType());
            receiver.sendText(JSON.toJSONString(message));
        }

        // 用户在线
        if (receiver != null){
            // 设置发送状态为发送成功
            message.setStatus(MessageStatus.SENDSUCCESS.getStatus());
            receiver.sendText(JSON.toJSONString(message));
        }

        // 持久化消息到mongodb
        sendMsgVoService.add(message);
        return new Result(true, StatusCode.OK,"发送成功",message.getLabel());
    }

    /**
     * 查询当前在线人数
     * @return
     */
    @Operation(summary = "查询当前在线人数",description = "所需权限：",security ={@SecurityRequirement(name ="Authorization")})
    @GetMapping("/number")
    public Result Number(){
        if (myWebSocketClient.chatClients != null && myWebSocketClient.chatClients.size() > 0){
            return new Result(true, StatusCode.OK,"查询成功",myWebSocketClient.chatClients.size());
        }else {
            return new Result(false, StatusCode.ERROR,"当前无人在线！");
        }
    }

    /**
     * 获取与某好友的聊天记录
     * @return
     */
    @Operation(summary = "获取与某好友的聊天记录",description = "所需权限：",security ={@SecurityRequirement(name ="Authorization")})
    @PostMapping("/msg/list")
    public Result MsgList(@Validated @RequestBody MsgListVo msgListVo){
        List<SendMsgVo> sendMsgVoPage = sendMsgVoService.findMsgListBySenderAndReceiver(msgListVo);

        // 未读消息集合 根据label排序
        List<SendMsgVo> unReadList = sendMsgVoPage.stream()
                .filter(item -> {
                    return item.getStatus() == MessageStatus.SENDSUCCESS.getStatus();
                })
                .sorted((m1, m2) -> {
                    return m1.getLabel() - m2.getLabel();
                }).collect(Collectors.toList());

        // 已读读消息集合 根据label排序
        List<SendMsgVo> readList = sendMsgVoPage.stream()
                .filter(item -> {
                    return item.getStatus() == MessageStatus.READ.getStatus();
                })
                .sorted((m1, m2) -> {
                    return m1.getLabel() - m2.getLabel();
                }).collect(Collectors.toList());

        Map resultMap = new HashMap<String,List<SendMsgVo>>();
        resultMap.put("unread",unReadList);
        resultMap.put("read",readList);

        return new Result(true, StatusCode.OK,"查询成功",resultMap);
    }


    /**
     * 获取与某好友的未读聊天记录
     * @return
     */
    @Operation(summary = "获取与某好友的未读聊天记录",description = "所需权限：",security ={@SecurityRequirement(name ="Authorization")})
    @PostMapping("/msg/list/unread")
    public Result UnreadMsgList(@Validated @RequestBody MsgListVo msgListVo){
        List<SendMsgVo> msgListBySender = sendMsgVoService.findUnReadMsgList(msgListVo);
        return new Result(true, StatusCode.OK,"查询成功",msgListBySender);
    }

    /**
     * 获取所有的的未读聊天记录
     * @return
     */
    @Operation(summary = "获取所有的的未读聊天记录",description = "所需权限：",security ={@SecurityRequirement(name ="Authorization")})
    @GetMapping("/msg/list/AllUnread")
    public Result AllUnreadMsgList(@RequestParam(value = "userId") Long userId){
        List<SendMsgVo> msgListBySender = sendMsgVoService.findAllUnReadMsgList(userId);
        return new Result(true, StatusCode.OK,"查询成功",msgListBySender);
    }


    /**
     * 更新与某好友的未读聊天记录状态
     * @return
     */
    @Operation(summary = "更新与某好友的未读聊天记录状态",description = "所需权限：",security ={@SecurityRequirement(name ="Authorization")})
    @PutMapping("/msg/status")
    public Result TransfromToRead(@Validated @RequestBody UpdateMsgStatusVo updateMsgStatusVo){
        // 更新mongodb
        sendMsgVoService.updateMsgStatus(updateMsgStatusVo);
        // 发送通知
        Session receiver = myWebSocketClient.chatClients.get(updateMsgStatusVo.getFriendId());
        return new Result(true, StatusCode.OK,"读取成功");
    }

}
